# import panda main module
import direct.directbase.DirectStart

import math

from pandac.PandaModules import *
from direct.showbase import *
# module for task controlling
from direct.task import Task

# load configuration file (carica file di configurazione)
import conf

mouse_wheel_command = {'up':'out', 'down':'in'}
if conf.zoom_inv:
    # rotella su => zoom in e viceversa
    mouse_wheel_command = {'up':'in', 'down':'out'}    

# Class that loop through events
class EventsHandler(DirectObject.DirectObject):
    
    # inizializzazione solo con camera?
    def __init__(self, camera):
        # camera objects
        self.camera = camera
        
        # true if alt is clicked
        self.alt_pressed = False
        
        # accept camera rotation and movement events
        self.accept('MouseRight', self.camera.rotate, [-1])
        self.accept('MouseLeft', self.camera.rotate, [1])
        self.accept('MouseDown', self.camera.inclination, [-1])
        self.accept('MouseUp', self.camera.inclination, [1])
        
        # D key => move right
        d_key_def = lambda task: self.start_moving('right', task)
        self.accept('time-d', taskMgr.add, [d_key_def, 'RightCamera'])
        self.accept('time-d-up', lambda event: taskMgr.remove('RightCamera'))
        # A key => move left
        a_key_def = lambda task: self.start_moving('left', task)
        self.accept('time-a', taskMgr.add, [a_key_def, 'LeftCamera'])
        self.accept('time-a-up', lambda event: taskMgr.remove('LeftCamera'))
        # W key => move Up
        w_key_def = lambda task: self.start_moving('up', task)
        self.accept('time-w', taskMgr.add, [w_key_def, 'UpCamera'])
        self.accept('time-w-up', lambda event: taskMgr.remove('UpCamera'))
        # S key => move Down
        s_key_def = lambda task: self.start_moving('down', task)
        self.accept('time-s', taskMgr.add, [s_key_def, 'DownCamera'])
        self.accept('time-s-up', lambda event: taskMgr.remove('DownCamera'))
        
        self.accept('mouse3', self.switch_alt)
        self.accept('mouse3-up', self.switch_alt)
        
        # zoom on wheel roll (DONE: config file for inversion)        
        self.accept('wheel_up', self.zoom, [mouse_wheel_command['up']])
        self.accept('wheel_down', self.zoom, [mouse_wheel_command['down']])
    
    # manages zoom and camera rotation
    def zoom(self, direction):
        if self.alt_pressed:
            rotate_value = {'out':5, 'in':-5}[direction]
            self.camera.camera_rotate(rotate_value)
        else:
            self.camera.camera_zoom(direction)
    
    def start_moving(self, direction, task):
        self.move_camera(direction)
        
        return task.cont
    
    def move_camera(self, direction):
        # angle of the camera in radians
        radians = (self.camera.horizontalAngle / 360.0) * 6.28
        # sin and cos of the angle
        ax = math.sin(radians)
        ay = math.cos(radians)
        
        if direction == 'up':
            self.camera.move(ax*-3, ay*3)
        elif direction == 'down':
            self.camera.move(ax*3, ay*-3)
        elif direction == 'left':
            self.camera.move(ay*-3, ax*-3)
        elif direction == 'right':
            self.camera.move(ay*3, ax*3)
    
    def switch_alt(self):
        self.alt_pressed = not self.alt_pressed
